package com.wmx.newspushmonitor;

import android.Manifest;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.app.Activity;
import android.app.AppOpsManager;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.provider.Settings;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.GravityCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.accessibility.AccessibilityManager;
import android.widget.Button;

import com.rhino.ui.utils.ui.ToastUtils;
import com.wmx.newspushmonitor.base.BaseSimpleTitleHttpActivity;
import com.wmx.newspushmonitor.databinding.ActivityMainBinding;
import com.wmx.newspushmonitor.notification.MyNotificationListenerService;
import com.wmx.newspushmonitor.ui.NewsInfoAdapter;
import com.wmx.newspushmonitor.ui.NewsInfoItem;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;

public class MainActivity extends BaseSimpleTitleHttpActivity<ActivityMainBinding>
        implements AccessibilityManager.AccessibilityStateChangeListener, MyPushReceiver.OnReceivedPushListener {
    private static final String TAG = "MainActivity";

    private AccessibilityManager accessibilityManager;
    private RecyclerView mNewsInfoRecycleView;
    private NewsInfoAdapter mAdapter;
    private MyPushReceiver mMyPushReceiver;

    public static void show(Activity activity) {
        Intent intent = new Intent(activity, MainActivity.class);
        activity.startActivity(intent);
    }

    @Override
    public void setContent() {
        setContentView(R.layout.activity_main);
    }

    @Override
    public void initView() {
        mActionBarHelper.setTitle(getString(R.string.app_name));
        mActionBarHelper.setTitleBackKeyVisible(false);
        mActionBarHelper.addTitleRightKey(R.drawable.ic_action_setting, new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(getApplicationContext(), NotifySettingActivity.class));
            }
        });
        mNewsInfoRecycleView = (RecyclerView) findViewById(R.id.newsinfo_recycler_view);
        mNewsInfoRecycleView.setLayoutManager(new LinearLayoutManager(this));
        mNewsInfoRecycleView.addItemDecoration(
                new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
        mAdapter = new NewsInfoAdapter();
        mNewsInfoRecycleView.setAdapter(mAdapter);

        initAccessibilityService();
        handleIntent(getIntent());
        setBaseOnClickListener(dataBinding.btOpenServer1, dataBinding.btOpenServer2);

        mMyPushReceiver = new MyPushReceiver(this);
        registerReceiver(mMyPushReceiver, new IntentFilter(MyPushReceiver.ACTION_RECEIVE_PUSH));
        MyNotificationListenerService.startService(this);
    }

    @Override
    public void onAccessibilityStateChanged(boolean enabled) {
        updateMonitorStatus();
        updateNotifyEnable();
    }

    @Override
    public void onResume() {
        super.onResume();
        updateMonitorStatus();
        updateNotifyEnable();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mMyPushReceiver != null) {
            unregisterReceiver(mMyPushReceiver);
            mMyPushReceiver = null;
        }
    }

    @Override
    protected void onNewIntent(Intent intent) {
        handleIntent(intent);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
//        if (dispatchKeyDown(keyCode, event)) {
//            return true;
//        }
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            moveTaskToBack(false);
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    public void baseOnClickListener(View v) {
        super.baseOnClickListener(v);
        if (v == dataBinding.btOpenServer1) {
            Intent accessibleIntent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
            startActivity(accessibleIntent);
        } else if (v == dataBinding.btOpenServer2) {
            startActivity(new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS));
        }
    }

    @Override
    public void onReceived(String newsInfo, String packageName) {
        if (!TextUtils.isEmpty(packageName)){
            mAdapter.addNewsInfoItem(new NewsInfoItem(packageName, newsInfo));
        }
    }

    private void initAccessibilityService() {
        accessibilityManager = (AccessibilityManager) getSystemService(Context.ACCESSIBILITY_SERVICE);
        accessibilityManager.addAccessibilityStateChangeListener(this);
    }

    private void handleIntent(Intent intent) {
        String newsInfo = intent.getStringExtra("newsInfo");
        String packageName = intent.getStringExtra("packageName");
        if (!TextUtils.isEmpty(packageName)){
            mAdapter.addNewsInfoItem(new NewsInfoItem(packageName, newsInfo));
        }
    }

    private void updateMonitorStatus() {
        String statusStr;
//        if (isServiceEnabled()) {
//            statusStr = getString(R.string.close_service);
//        } else {
//            statusStr = getString(R.string.start_service);
//        }
//        dataBinding.btOpenServer1.setText(statusStr);
//        if (isServiceEnabled()) {
//            dataBinding.btOpenServer1.setVisibility(View.GONE);
//        } else {
//            dataBinding.btOpenServer1.setVisibility(View.VISIBLE);
//        }
    }

    private void updateNotifyEnable() {
        String statusStr;
//        if (isServiceEnabled()) {
//            statusStr = getString(R.string.close_service);
//        } else {
//            statusStr = getString(R.string.start_service);
//        }
//        dataBinding.btOpenServer1.setText(statusStr);
//        if (isNotificationEnabled(getApplicationContext())) {
//            dataBinding.btOpenServer2.setVisibility(View.GONE);
//        } else {
//            dataBinding.btOpenServer2.setVisibility(View.VISIBLE);
//        }
    }

    private boolean isServiceEnabled() {
        List<AccessibilityServiceInfo> accessibilityServices =
                accessibilityManager.getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_GENERIC);
        for (AccessibilityServiceInfo info : accessibilityServices) {
            if (info.getId().equals(getPackageName() + "/.PushMonitorAccessibilityService")) {
                return true;
            }
        }
        return false;
    }

    private boolean isNotificationEnabled(Context context) {
        String CHECK_OP_NO_THROW = "checkOpNoThrow";
        String OP_POST_NOTIFICATION = "OP_POST_NOTIFICATION";
        AppOpsManager mAppOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
        ApplicationInfo appInfo = context.getApplicationInfo();
        String pkg = context.getApplicationContext().getPackageName();
        int uid = appInfo.uid;

        Class appOpsClass = null;
        /* Context.APP_OPS_MANAGER */
        try {
            appOpsClass = Class.forName(AppOpsManager.class.getName());
            Method checkOpNoThrowMethod = appOpsClass.getMethod(CHECK_OP_NO_THROW, Integer.TYPE, Integer.TYPE,
                    String.class);
            Field opPostNotificationValue = appOpsClass.getDeclaredField(OP_POST_NOTIFICATION);

            int value = (Integer) opPostNotificationValue.get(Integer.class);
            return ((Integer) checkOpNoThrowMethod.invoke(mAppOps, value, uid, pkg) == AppOpsManager.MODE_ALLOWED);

        } catch (Exception e) {
            e.printStackTrace();
        }


        return false;
    }


}
